package threadState;

/**
 * 演示线程状态切换（第二遍）
 */
public class ThreadStateDemo2 {
    public static void main(String[] args) throws InterruptedException {
        System.out.println("========== new -> runnable -> terminated ===================");
        Thread t1 = new Thread(() -> {
            System.out.println("thread1 running");
            System.out.println("thread1 state -> " + Thread.currentThread().getState());
            System.out.println("thread1 exit");
        });
        System.out.println("thread1 state -> " + t1.getState());
        System.out.println("start thread1");
        t1.start();
        System.out.println("main sleep 200");
        Thread.sleep(200);
        System.out.println("thread1 state -> " + t1.getState());

        System.out.println("\n\n========== new -> runnable -> waiting -> runnable -> terminated ===================");
        Object o2 = new Object();
        Thread t2 = new Thread(() -> {
            System.out.println("thread2 running");
            System.out.println("thread2 state -> " + Thread.currentThread().getState());
            synchronized (o2) {
                System.out.println("waiting for o2 notify");
                try {
                    o2.wait();
                    System.out.println("thread2 state -> " + Thread.currentThread().getState());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("thread2 exit");
        });
        System.out.println("thread2 state -> " + t2.getState());
        System.out.println("start thread2");
        t2.start();
        System.out.println("main sleep 200");
        Thread.sleep(200);
        System.out.println("thread2 state -> " + t2.getState());
        synchronized (o2) {
            System.out.println("notify o2");
            o2.notify();
        }
        System.out.println("main sleep 200");
        Thread.sleep(200);
        System.out.println("thread2 state -> " + t2.getState());

        System.out.println("\n\n========== new -> runnable -> blocked -> runnable -> terminated ===================");
        Object o3 = new Object();
        Thread t3 = new Thread(() -> {
            System.out.println("thread3 running");
            System.out.println("thread3 state -> " + Thread.currentThread().getState());
            synchronized (o3) {
                System.out.println("thread3 get o3 monitor");
                System.out.println("thread3 state -> " + Thread.currentThread().getState());
            }
            System.out.println("thread3 exit");
        });
        System.out.println("thread3 state -> " + t3.getState());
        synchronized (o3) {
            System.out.println("main get o3 monitor");
            System.out.println("start thread2");
            t3.start();
            System.out.println("main sleep 200");
            Thread.sleep(200);
            System.out.println("thread3 state -> " + t3.getState());
            System.out.println("main release o3 monitor");
        }
        System.out.println("main sleep 200");
        Thread.sleep(200);
        System.out.println("thread3 state -> " + t3.getState());
    }
}
